/*
 * 编程统计字符串"ABCD123!@#$%ab"中大写字母、小写字母、数字、其它字符的个数并打印出来。
 *
 * 这道题考察的是字符串常用函数和正则匹配规则
 */

package com.syxbyi._1count;

import org.jetbrains.annotations.NotNull;

public class Counter {
    final String str = "ABCD123!@#$%ab";

    // 测试函数
    private void printSubStrings(String @NotNull [] subStrings) {
        for ( String s : subStrings ) {
            if (s.isEmpty()) {
                System.out.println("NULL");
                continue;
            }
            System.out.println(s);
        }
    }

    // 一种简单的方法，直接使用字符串分割，根据得到几个子字符串判断有几个对应字符
    // 注：split函数参数limit=-1是为了保留结尾的空字符串，否则在本例中计算小写字母函数得不到正确答案（以下是split文档说明）
    // If the limit is negative then the pattern will be applied as many times as possible and the array can have any length.
    public int countDigital() {
        String[] subs = str.split("\\d", -1);
        return subs.length - 1;
    }

    public int countUpperCase() {
        String[] subs = str.split("[A-Z]", -1);
        return subs.length - 1;
    }

    public int countLowerCase() {
        String[] subs = str.split("[a-z]", -1);
        return subs.length - 1;
    }

    public int countOtherChar() {
        String[] subs = str.split("\\W", -1);
        return subs.length - 1;
    }

    // 另一种计算方法
    // 可以打印出执行流程 “发现大写字母XXX，目前大写字母已有X个”
    public int countUpperCase2() {
        int i = 0;
        int count = 0;
        char c;
        while (i < str.length()) {
            if ((c = str.charAt(i)) <= 'Z' && c >= 'A') {
                count++;
                System.out.printf("遍历法统计大写：找到第%d个大写字符%c\n", count, c);
            }
            i++;
        }
        return count;
    }

    public static void main(String[] args) {
        Counter c = new Counter();
        System.out.println("分割法统计数字：" + c.countDigital());
        System.out.println("分割法统计大写：" + c.countUpperCase());
        System.out.println("分割法统计小写：" + c.countLowerCase());
        System.out.println("分割法统计其他：" + c.countOtherChar());
        System.out.println("遍历法统计大写：" + c.countUpperCase2());
    }
}
